package com.liyghting.mutildb.config;

import javax.sql.DataSource;

import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.mybatis.spring.boot.autoconfigure.MybatisProperties;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import com.zaxxer.hikari.HikariDataSource;

@Configuration
@ConditionalOnClass({ SqlSessionFactory.class, SqlSessionFactoryBean.class })
@MapperScan(basePackages = { MultiAdbMybatisConfig.BASE_DAO_SCAN }, sqlSessionFactoryRef = "adbSqlSessionFactory")
public class MultiAdbMybatisConfig {

	protected static final String BASE_DAO_SCAN = "com.liyghting.mutildb.adb";

	@Bean
	@ConfigurationProperties(prefix = "adbDataSource")
	public DataSourceProperties adbDataSourceProperties() {
		DataSourceProperties adbDataSourceProperties = new DataSourceProperties();
		return adbDataSourceProperties;
	}

	@Bean
	@ConditionalOnBean(name = "adbDataSourceProperties")
	public DataSource adbDataSource() {
		DataSourceProperties adbDataSourceProperties = adbDataSourceProperties();
		return adbDataSourceProperties.initializeDataSourceBuilder().type(HikariDataSource.class).build();
	}

	@Bean
	@ConditionalOnBean(name = "adbDataSource")
	public DataSourceTransactionManager adbTransactionManager() {
		DataSource adbDataSource = adbDataSource();
		return new DataSourceTransactionManager(adbDataSource);
	}

	@Bean
	@ConfigurationProperties("adbMybatis")
	public MybatisProperties adbMybatisProperties() {
		MybatisProperties adbMybatisProperties = new MybatisProperties();
		return adbMybatisProperties;
	}

	@Bean
	@ConditionalOnBean(name = { "adbMybatisProperties", "adbDataSource" })
	public SqlSessionFactory adbSqlSessionFactory() throws Exception {
		MybatisProperties adbMybatisProperties = adbMybatisProperties();
		DataSource adbDataSource = adbDataSource();
		final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
		sessionFactory.setDataSource(adbDataSource);
		sessionFactory.setMapperLocations(adbMybatisProperties.resolveMapperLocations());
		sessionFactory.setConfiguration(adbMybatisProperties.getConfiguration());
		return sessionFactory.getObject();
	}

}
